package com.sld.integrate.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.sld.integrate.domain.InfoConcreteRegister;
import com.sld.integrate.domain.RecDevWorkSequence;
import com.sld.integrate.domain.RecDevWorkStandard;
import com.sld.integrate.domain.RelateDeviceVehicle;
import com.sld.integrate.mapper.InfoConcreteRegisterMapper;
import com.sld.integrate.mapper.RecDevWorkSequenceMapper;
import com.sld.integrate.mapper.RecDevWorkStandardMapper;
import com.sld.integrate.mapper.RelateDeviceVehicleMapper;
import com.sld.integrate.service.IDevWorkSequenceService;
import com.sld.integrate.vo.CalculateTuple;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * 描述:
 *
 * @Author tanli
 * @create 2022-04-05 10:57
 */
@Slf4j
@Service
public class DevWorkSequenceServiceImpl implements IDevWorkSequenceService {

    @Resource
    RecDevWorkSequenceMapper sequenceMapper;

    @Resource
    RelateDeviceVehicleMapper relateDeviceVehicleMapper;

    @Resource
    InfoConcreteRegisterMapper registerMapper;

    @Resource
    RecDevWorkStandardMapper standardMapper;

    //@Cacheable(value="workSequenceInfo", key="#devId", unless="#result == null")
    @Override
    public RecDevWorkSequence queryDevRecentlyWorkInfo(String devId) {
        return sequenceMapper.queryDevRecentlyWorkInfo(devId);
    }

    //@Cacheable(value="workSequenceInfo", key="#sequence.devId")
    @Override
    public RecDevWorkSequence insert(RecDevWorkSequence sequence) {
        sequenceMapper.insert(sequence);
        return sequence;
    }

    //@Cacheable(value="workSequenceInfo", key="#sequence.devId")
    @Override
    public int update(RecDevWorkSequence sequence) {
        return sequenceMapper.updateById(sequence);
    }

    @Override
    public RecDevWorkSequence createOrGetRecentlyWorkSequence(String devId) {
        RecDevWorkSequence sequence = queryDevRecentlyWorkInfo(devId);
        if (sequence == null) {
            log.info("【开始】devId={} 开始新车次，state=1", devId);
            return createWorkSequence(devId, "01");
        }

        Date startTime = sequence.getStartTime();
        long betweenMinutes = DateUtil.between(startTime, new Date(), DateUnit.MINUTE);
        if (betweenMinutes < 2) {
            return sequence;
        }
        // 强行结束序列
        sequence.setEndTime(new Date());
        sequenceMapper.updateById(sequence);

        // gmtDate与 startTime处于一天，就 +1，否则从新开始计数。
        String workSequence = sequence.getWorkSequence();
        if (DateUtils.isSameDay(startTime, new Date())) {
            int nextSeq = Integer.parseInt(workSequence) + 1;
            workSequence = String.format("%02d", nextSeq);
        }
        // 生成新记录
        return createWorkSequence(devId, workSequence);
    }

    @Override
    public RecDevWorkSequence createWorkSequence(String devId, String workSequence){
        RecDevWorkSequence sequence = new RecDevWorkSequence();
        sequence.setDevId(devId);
        RelateDeviceVehicle relateDeviceVehicle = relateDeviceVehicleMapper.selectByDeviceId(devId);
        if (relateDeviceVehicle != null) {
            sequence.setPlateNo(relateDeviceVehicle.getPlateNo());
        }
        sequence.setWorkDate(LocalDate.now());
        sequence.setWorkSequence(workSequence);
        sequence.setStartTime(new Date());
        sequence.setInsertTime(new Date());
        sequenceMapper.insert(sequence);
        log.info("new work sequence save success. seqId={}", sequence.getId());
        return sequence;
    }

    @Override
    public int createWorkSequenceConcreteBinding(RecDevWorkSequence sequence) {
        //尝试关联，并不一定能找到混凝土注册信息
        String plateNo = sequence.getPlateNo();
        if (StringUtils.isEmpty(plateNo)) {
            log.error("dev={}该设备没有绑定车牌号，无法绑定登记信息", sequence.getDevId());
            return -1;
        }

        // 用车牌查找没有被绑定的记录，时间倒序，最近一个关联上
        InfoConcreteRegister registerInfo = registerMapper.queryLastRegisterInfo(plateNo);
        if (registerInfo == null) {
            log.info("本次运输未找到登记信息。plateNo={}，workSeq={}", plateNo, sequence.getId());
            return -1;
        }

        registerInfo.setBindState("1");
        registerInfo.setBindTime(new Date());
        registerInfo.setWorkDate(sequence.getWorkDate());
        registerInfo.setWorkSeqId(sequence.getId());
        registerMapper.updateById(registerInfo);
        // 更新sequence bind信息。
        sequence.setRegisterId(registerInfo.getRegisterId());
        sequenceMapper.updateById(sequence);

        return registerInfo.getRegisterId();
    }

    @Override
    public int saveCalibrationValue(Integer seqId, CalculateTuple tuple) {
        RecDevWorkStandard standard = new RecDevWorkStandard();
        standard.setWorkSeqId(seqId); // 自己赋值
        standard.setPressure(tuple.getPressure());
        standard.setSpeed(tuple.getSpeed());
        standard.setTemperature(tuple.getTemperature());
        standard.setHumidity(tuple.getHumidity());
        String messages = tuple.getMessages().stream().map(item -> item.getMsgId().toString()).collect(Collectors.joining(","));
        standard.setMessageIds(messages);
        standard.setInsertTime(new Date());

        return standardMapper.insert(standard);
    }

    @Override
    public RecDevWorkStandard queryCalibrationValue(Integer id) {
        return standardMapper.selectById(id);
    }

}
